package cn.com.utils.crypto;

import cn.hutool.core.io.FileUtil;
import com.sun.jna.Library;
import com.sun.jna.Native;

import java.util.Optional;

/**
 * 调用加解密动态库
 * <br>
 * JNA 调用系统SO方法，下面的方法是NATIVE方法
 * <h2>名称和参数不可随意变更</h2>
 **/
public interface Clibrary extends Library {

    /**
     * 动态库路径
     */
    String VAR_RC_LINK = "VAR_RC_LINK";

    /**
     * [Native.synchronizedLibrary] 阻止多线程同时访问本地代码
     */
    Clibrary INSTANCE = Optional.ofNullable(System.getenv(VAR_RC_LINK))
            .map(link -> {
                return (Clibrary) Native.synchronizedLibrary(
                        Native.load(FileUtil.file(link).getPath(), Clibrary.class));
            }).orElse(Optional.ofNullable(DataCryptoUtil.getKeyFile("crypto.dll"))
                    .map(FileUtil::getCanonicalPath)
                    .map(v -> (Clibrary) Native.synchronizedLibrary(Native.load(v, Clibrary.class)))
                    .orElse(null));


    /**
     * 加密
     *
     * @param plaintext 明文
     * @return {@link String}
     */
    String Encrypt(GoString.ByValue plaintext);

    /**
     * 解密
     *
     * @param ciphertext 密文
     * @return {@link String}
     */
    String Decrypt(GoString.ByValue ciphertext);

    /**
     * 使用索引解密
     *
     * @param index      索引
     * @param ciphertext 密文
     * @return {@link String}
     */
    String DecryptWithIndex(int index, GoString.ByValue ciphertext);

    /**
     * 初始化
     *
     * @param basePath  根密钥路径
     * @param stackPath 工作密钥栈路径
     */
    void Init(GoString.ByValue basePath, GoString.ByValue stackPath);

}
